/*
 * Copyright 2009-2010 the original author or authors.
 *
 * Licensed under the Apache license, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package org.internna.iwebjtracker.services;

import java.util.Date;
import javax.servlet.http.HttpServletRequest;
import org.internna.iwebjtracker.project.model.IWebJTrackerUser;
import org.internna.iwebjtracker.project.model.Module;
import org.internna.iwebjtracker.project.model.Project;
import org.internna.iwebjtracker.project.model.Version;
import org.internna.iwebjtracker.project.validation.ProjectValidator;
import org.internna.iwebjtracker.server.connection.ConnectionDetails;
import org.internna.iwebmvc.model.UUID;

/**
 * Remote operations to handle the Project entity.
 *
 * @author Jose Noheda
 * @since 1.0
 */
public interface ProjectManager<C extends ConnectionDetails, M extends Module<P, M>, V extends Version<U, P, V>, U extends IWebJTrackerUser, P extends Project<C, M, V, U, P>> extends ProjectValidator <C, M, V, U, P> {

    /**
     * Persists a new project with an initial provided version.
     * 
     * @param project any project
     * @param version any
     * @param request the current request
     * @return the modified project
     */
    P createProject(P project, String version, HttpServletRequest request);

    /**
     * Request to become an observer in a project.
     *
     * @param project any
     */
    void joinProject(UUID project, HttpServletRequest request);

    /**
     * Allows a user to update basic project data.
     *
     * @param id a valid, not null, primary key of a project entity (otherwise no changes processed)
     * @param name a not empty string (otherwise ommitted)
     * @param alias a not empty string (otherwise ommitted)
     * @param description a not empty string (otherwise ommitted)
     * @param url a not empty string (otherwise ommitted)
     * @param logo any
     * @param isPublic any
     */
    void editProjectSettings(UUID id, String name, String alias, String description, String url, UUID logo, boolean isPublic);

    /**
     * Adds a new module to a project or component to a module.
     *
     * @param project if null it considers it a component addition
     * @param module any
     * @param name any
     * @param description any
     * @return null unless a module was created. Then the geenrated id
     */
    UUID createModule(UUID project, UUID module, String name, String description);

    /**
     * Changes a module or component name and/or description.
     *
     * @param id any
     * @param name any
     * @param description any
     */
    void changeModule(UUID id, String name, String description);

    /**
     * Adds a new member to a project. It can be added as developer or administrator.
     *
     * @param project any
     * @param trackerUser any
     * @param asAdministrator true for entity owners
     * @return true if the project has a new member
     */
    boolean addProjectMember(UUID project, UUID trackerUser, boolean asAdministrator);

    /**
     * Adds a new version to this project.
     *
     * @param project any
     * @param version any (version overrides project parameter)
     * @param name any (if empty no version will be created)
     * @param due any
     */
    UUID createVersion(UUID project, UUID version, String name, Date due);

    /**
     * Changes a version or milestone label and/or end date.
     *
     * @param id any (usually a valid version primary key)
     * @param label any (if null or empty no action will be performed)
     * @param due any
     */
    void changeVersion(UUID id, String label, Date due);

    /**
     * Sets this version as the current version for this project.
     *
     * @param project any (usually a valid project primary key)
     * @param version any (usually a valid version primary key)
     * @return true if the version now has the current flag set to true
     */
    boolean setAsCurrentVersion(UUID project, UUID version);

    /**
     * Closes the project provided.
     *
     * @param project any
     * @return the i18n translated error if any, null if project was successfully closed.
     */
    String closeProject(UUID project);

    /**
     * Reopens a previously open project.
     *
     * @param project any
     * @return the i18n translated error if any, null if project was successfully opened
     */
    String reopenProject(UUID project);

    /**
     * Closes the version provided.
     *
     * @param version any
     * @return the i18n translated error if any, null if version was successfully closed.
     */
    String closeVersion(UUID version);

}
